package control;

import java.util.ArrayList;
import java.util.LinkedList;
import java.util.List;
import java.util.Scanner;

import registers.RegisterManager;

import data.*;
import directions.DirectionsMenu;
import factory.MenuStarter;

/**
 * @author Steve
 * Driver class for the Team Rocky Road Project
 * Baskin Robins/Dunkin Donuts Register Service
 */
public class RockyRoad {
	@SuppressWarnings("unused")
	private static String state = "";
	private static String store = "both";
	private static double tax = 0;
	private static Order orderItem;
	private static ArrayList<Order> items = new ArrayList<Order>(); 
	private static ArrayList<String> menu = new ArrayList<String>(); 
	private static RegisterManager reg;
	private static int currentRegister = 1;
	@SuppressWarnings("unused")
	private static Scanner in;
	@SuppressWarnings("unused")
	private static DirectionsMenu dir;

	/**
	 * Driver
	 * @param args
	 */
	public static void main(String[] args) {
		topPrompt();
		createMenu();
		getOptions();
		menu();
	}

	/**
	 * adds menu options to list
	 */
	private static void createMenu() {
		menu.add("Change Register");
		menu.add("Create an Order");
		menu.add("Display an Order");
		menu.add("Remove and Print an Order");
		menu.add("Exit");	
	}

	/**
	 * Displays main driver menu
	 */
	@SuppressWarnings("static-access")
	private static void menu() {
		reg = new RegisterManager(2, tax);

		while(true){
			System.out.println("Current Register #: " + currentRegister); 
			int choice = presentMenu(menu);
			if (choice == 0){
				LinkedList<String> args = new LinkedList<String>();
				for(int arg : (reg.getRegisterNumbers()))
					args.add("Register " + String.valueOf(arg));

				currentRegister = presentMenu(args) + 1;

			}
			else if (choice == 1){
				// FIXME add unique order to list
				// I cant figure out why I'm only able to add a reference to the list 
				// but not a clone.  I've tried many different things and ideas over the last 
				// couple hours, and unable to find a solution.
				orderItem = new Order(MenuStarter.getOrder());
				orderItem.setRegister(currentRegister);
				items.add(new Order(orderItem));

			}
			else if (choice == 2){
				try{
					if(!items.isEmpty())
						dir = new DirectionsMenu(getOrder(false).toLine());
					else
						System.out.println("nothing to show");
					pauseProg();
				} catch (NullPointerException npe){
					System.out.println("nothing to show");
					pauseProg();
				}
			}
			else if (choice == 3){
				try{
					orderItem = getOrder(true);
					reg.printReceipt(orderItem);
					reg.handleMoney(orderItem);
					pauseProg();
				} catch (NullPointerException npe){
					System.out.println("nothing to print and remove");
					pauseProg();
				}				
			}
			else{
				System.out.println("Goodbye");
				break;
			}
		}
	}

	/**
	 * If not called, Menu will assume the store is both and tax of 0.00
	 * Gets Store type and tax value from options menu
	 */
	private static void getOptions() {
		LinkedList<String> args = new LinkedList<String>();
		for(String arg : MenuStarter.getOption().toLine().split(","))
			args.add(arg);
		while(!args.isEmpty()){
			if(args.peek().equalsIgnoreCase("State")){
				args.pop();
				state = args.pop();
				tax = Double.parseDouble(args.pop());
			}
			else if (args.peek().equalsIgnoreCase("Store")){
				args.pop();
				store = args.pop();
			}
			else
				args.pop();
		}
//		System.out.println(state + " " + tax + " " + store);
		setOptions();
	}

	/**
	 * Sets to correct menu based on store
	 */
	private static void setOptions() {
		MenuStarter.setStore(store);	
	}

	/**
	 * Opening prompt for program
	 */
	private static void topPrompt() {
		System.out.println("Baskin Robins/Dunkin Donuts Register Service");	
	}

	/**
	 * @param choices menu choices
	 * @return choice made
	 */
	private static int presentMenu(List<String> choices){
		Scanner in = new Scanner(System.in);
		StringBuffer sb = new StringBuffer();

		System.out.println("\nPlease enter an option:");
		for(int i=0; i<choices.size(); i++)
			sb.append(i).append(") ").append(choices.get(i)).append("\n");

		int choice = -1;
		boolean first = true;
		while(choice == -1){
			if(!first)
				System.out.println("\nThis is not a valid choice, try again.\n");
			first = false;

			System.out.println(sb.toString());

			try{
				choice = Integer.parseInt(in.nextLine());
			} catch (NumberFormatException nfe) {
				choice = -1;
			}
			if(choice < 0 || choice >= choices.size())
				choice = -1;
		}
		return choice;
	}

	/**
	 * @param remove boolean to remove item from list or not
	 * @return Order item
	 */
	@SuppressWarnings({ "static-access", "unused" })
	public static Order getOrder(boolean remove){
		Order order = null;
		Scanner in = new Scanner(System.in);

		ArrayList<String> choices = new ArrayList<String>();
		for(Order lm : items)
			choices.add(lm.toLine());

		if(choices.size() >0){

			int selection = presentMenu(choices);

			order = items.get(selection);

			choices.remove(selection);

			if (remove)
				items.remove(selection);
		}	
		return order;
	}

	private static void pauseProg(){
		System.out.println("Press enter to continue...");
		Scanner keyboard = new Scanner(System.in);
		keyboard.nextLine();
	}
}
